package com.test.demo.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.excel.EasyExcel;
import com.test.demo.util.ExportUtil;
import com.test.demo.util.ParamUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
public class DemoInfoService {

    /**
     * 油罐容积表数据对
     */
    protected Map<String, Object> volumeMap = new HashMap<>();
    //油品列表
    public static ConcurrentHashMap<String, Object> oilMap = new ConcurrentHashMap<>();


    public Map<String, Object> calculateHFile(MultipartFile file) throws IOException {
        Map<String, Object> result = new HashMap<>();
        result.put("code", "fail");


        List<Map<String, Object>> readList = EasyExcel.read(file.getInputStream()).sheet().doReadSync();
        if (CollUtil.isEmpty(readList)) {
            result.put("msg", "数据不能为空");
            return result;
        }
        Map<String, Object> first = readList.stream().findFirst().orElse(null);
        if (MapUtil.isEmpty(first)) {
            result.put("msg", "数据不能为空");
            return result;
        }
        log.info("####油品列表：" + oilMap);
        BigDecimal rate = BigDecimal.valueOf(0.001);
        List<Map<String, Object>> vtList = new ArrayList<>();
        Map<String, Object> vt = new HashMap<>();
        vt.put("taskSeriesNum", 1);
        vt.put("lossRate", rate.multiply(BigDecimal.valueOf(1000)).setScale(3, BigDecimal.ROUND_HALF_UP));
        vt.put("storageV20", 123);
        vt.put("stationV20", 123);
        vtList.add(vt);

        result.put("code", "succ");
        result.put("vtList", vtList);
        result.put("valueH", 1111);
        result.put("lossRate", rate.multiply(BigDecimal.valueOf(1000)).doubleValue());
        return result;
    }

    public Boolean uploadVolume(MultipartFile file) {

        //上传油品列表
        ClassPathResource resource = new ClassPathResource("oilList.txt");
        try (InputStream fileInputStream = resource.getInputStream()) {
            MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), fileInputStream);
            this.uploadOilList(multipartFile);
        } catch (Exception e) {
            log.error("油品导入异常", e);
        }

        //读取text格式文件内容
        Map<String, Object> volumeListTem = new HashMap<>();
        Boolean flag = combinTable(file, volumeListTem);
        if (Boolean.TRUE.equals(flag)) {
            volumeMap.clear();
            volumeMap.putAll(volumeListTem);
        }
        return flag;
    }

    /**
     * 读取text格式文件内容
     *
     * @param file
     * @return
     * @throws IOException
     */
    private Boolean combinTable(MultipartFile file, Map<String, Object> volumeListTem) {


        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {

            String tempString = null;
            String hBefore = "";
            String vBefore = "";
            //是否是csv文件的第一行
            boolean flag = true;
            // 一次读入一行，直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                if ("".equals(tempString.trim())) {
                    continue;
                }
                String[] nums = null;
                if (flag && file.getOriginalFilename().endsWith(".csv")) {
                    flag = false;
                    nums = tempString.split(" ");
                    if (ParamUtils.isNum(nums[0]) && ParamUtils.isNum(nums[1])) {
                        //csv容积表格式错误时
                        if (!isCsvValid(nums[0], nums[1], hBefore, vBefore)) {
                            return null;
                        }
                        hBefore = nums[0];
                        vBefore = nums[1];
                        volumeListTem.put(hBefore, vBefore);
                    }
                    continue;
                }
                if (tempString.indexOf("\t") == -1 && tempString.indexOf(" ") == -1 && tempString.indexOf(",") == -1) {
                    return null;
                }
                if (tempString.indexOf("\t") != -1) {
                    nums = tempString.trim().split("\t");
                } else if (tempString.indexOf(" ") != -1) {
                    nums = tempString.split(" ");
                } else {
                    nums = tempString.trim().split(",");
                }

                if (nums.length != 2) {
                    return null;
                } else {
                    if (isValid(nums[0], nums[1], hBefore, vBefore)) {
                        hBefore = nums[0];
                        vBefore = nums[1];
                        volumeListTem.put(hBefore, vBefore);
                    } else {
                        return null;
                    }
                }
            }
        } catch (Exception e) {
            log.error("导入异常", e);
        }
        return true;
    }

    /**
     * 验证csv容积表是否合法
     *
     * @param h
     * @param v
     * @param hBefore
     * @param vBefore
     * @return
     */
    private boolean isCsvValid(String h, String v, String hBefore, String vBefore) {
        if (hBefore.isEmpty() && vBefore.isEmpty()) {
            return true;
        }
        return (int) Double.parseDouble(h) > (int) Double.parseDouble(hBefore) && Float.parseFloat(v) > Float.parseFloat(vBefore);
    }

    /**
     * 验证xls/xlsx容积表是否合法
     *
     * @param h
     * @param v
     * @param hBefore
     * @param vBefore
     * @return
     */
    private boolean isValid(String h, String v, String hBefore, String vBefore) {
        if (hBefore.isEmpty() && vBefore.isEmpty()) {
            return ParamUtils.isNum(h) && ParamUtils.isNum(v);
        }
        return ParamUtils.isNum(h) && ParamUtils.isNum(v) && (int) Double.parseDouble(h) > (int) Double.parseDouble(hBefore) && Float.parseFloat(v) > Float.parseFloat(vBefore);
    }


    public Boolean uploadOilList(MultipartFile file) {
        //读取text格式的油品列表内容
        Map<String, Object> oilMapTem = new HashMap<>();
        Boolean flag = combinOil(file, oilMapTem);
        if (Boolean.TRUE.equals(flag)) {
            oilMap.clear();
            oilMap.putAll(oilMapTem);
        }
        log.info("####油品列表：" + oilMap);
        return flag;
    }

    /**
     * 读取text格式的油品内容
     *
     * @param file
     * @return
     * @throws IOException
     */
    private Boolean combinOil(MultipartFile file, Map<String, Object> oilMapTem) {
        //每行格式：编号,膨胀系数,标准密度(Kg/L),描述

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {

            String tempString;
            //是否是csv文件的第一行
            boolean flag = true;
            // 一次读入一行，直到读入null为文件结束
            while ((tempString = reader.readLine()) != null) {
                if ("".equals(tempString.trim())) {
                    continue;
                }
                String[] nums;
                if (flag && file.getOriginalFilename().endsWith(".csv")) {
                    flag = false;
                    nums = tempString.split(" ");
                    if (ParamUtils.isNum(nums[0]) && ParamUtils.isNum(nums[1])) {
                        oilMapTem.put(nums[3], nums[1]);
                    }
                    continue;
                }
                if (tempString.indexOf("\t") == -1 && tempString.indexOf(" ") == -1 && tempString.indexOf(",") == -1) {
                    return null;
                }
                if (tempString.indexOf("\t") != -1) {
                    nums = tempString.trim().split("\t");
                } else if (tempString.indexOf(" ") != -1) {
                    nums = tempString.split(" ");
                } else if (tempString.startsWith("#")) {
                    //注释
                    continue;
                } else {
                    nums = tempString.trim().split(",");
                }

                if (nums.length != 4) {
                    return null;
                } else {
                    oilMapTem.put(nums[3], nums[1]);
                }
            }
        } catch (Exception e) {
            log.error("导入异常", e);
        }
        return true;
    }

    public void exportOilInfo(HttpServletResponse response, String cnName) throws IOException {

        ClassPathResource resource = new ClassPathResource("oilList.txt");
        ExportUtil.exportTxtByPath(response, cnName, resource.getInputStream());
    }

}
